package com.lmx;

import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.base.Preconditions;
import com.lmx.common.util.PropertiesFileUtil;

@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-${envTarget:mysql}.properties" })
@ComponentScan({ "com.lmx.persistence" })
// @ImportResource("classpath*:springDataPersistenceConfig.xml")
@EnableJpaRepositories(basePackages = { "com.lmx.persistence.dao", "com.lmx.repoDomain" })
public class PersistenceConfig {

	private Log logger = LogFactory.getLog(this.getClass());
	
    @Autowired
    private Environment env;

    public PersistenceConfig() {
        super();
    }

	@Bean
	public JdbcTemplate jdbcTemplate() {//huibati
		return new JdbcTemplate(dataSource());
	}
    
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        //em.setPackagesToScan(new String[] { "com.lmx.repoDomain.model" });
        Properties properties = PropertiesFileUtil.getProperties("application.properties");
    	String serverLocalFalg=properties.getProperty("serverFlag.local");
		if (serverLocalFalg != null && !"false".equals(serverLocalFalg)){//  != false  &&   notnull  是本地服务   
            em.setPackagesToScan(new String[] {"com.lmx.repoDomain.local.tmodel" });  
    	}else{
            em.setPackagesToScan(new String[] {"com.lmx.repoDomain.tmodel" });  
    	}

        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        // vendorAdapter.set
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
//em.setSharedCacheMode(sharedCacheMode);
        return em;
    }

    @Bean
    public DataSource dataSource() {
        Properties properties = PropertiesFileUtil.getProperties("application.properties");
    	String serverLocalFalg=properties.getProperty("serverFlag.local");
		final DruidDataSource datasource = new DruidDataSource();
    	//  != false  &&   notnull  是本地服务    
    	if(serverLocalFalg!=null&&!"false".equals(serverLocalFalg)){
          datasource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.local.driverClassName")));
          datasource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.local.url")));
         // datasource.setMaxOpenPreparedStatements(0);
    	}else{
    		datasource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
    		datasource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
    		datasource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
    		datasource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
    		datasource.setValidationQuery(Preconditions.checkNotNull(env.getProperty("datasource.validationQuery")));
    		datasource.setPoolPreparedStatements(Boolean.parseBoolean(Preconditions.checkNotNull(env.getProperty("datasource.poolPreparedStatements"))));
    		datasource.setMaxPoolPreparedStatementPerConnectionSize(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.maxPoolPreparedStatementPerConnectionSize"))));
    		try {
    			datasource.setFilters((Preconditions.checkNotNull(env.getProperty("datasource.filters"))));
    		} catch (SQLException e) {
    			logger.debug("druid configuration initialization filter", e);
    		}
    	}
		// configuration
		datasource.setInitialSize(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.initialSize"))));
		datasource.setMinIdle(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.minIdle"))));
		datasource.setMaxActive(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.maxActive"))));
		datasource.setMaxWait(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.maxWait"))));
		datasource.setTimeBetweenEvictionRunsMillis(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.timeBetweenEvictionRunsMillis"))));
		datasource.setMinEvictableIdleTimeMillis(Integer.parseInt(Preconditions.checkNotNull(env.getProperty("datasource.minEvictableIdleTimeMillis"))));
		datasource.setTestWhileIdle(Boolean.parseBoolean(Preconditions.checkNotNull(env.getProperty("datasource.testWhileIdle"))));
		datasource.setTestOnBorrow(Boolean.parseBoolean(Preconditions.checkNotNull(env.getProperty("datasource.testOnBorrow"))));
		datasource.setTestOnReturn(Boolean.parseBoolean(Preconditions.checkNotNull(env.getProperty("datasource.testOnReturn"))));
		datasource.setConnectionProperties(Preconditions.checkNotNull(env.getProperty("datasource.connectionProperties")));
		return datasource;
    	
//        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
//        dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
//        dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
//        dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
//        dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));


    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    final Properties additionalProperties() {
        final Properties hibernateProperties = new Properties();
        Properties properties = PropertiesFileUtil.getProperties("application.properties");
    	String serverLocalFalg=properties.getProperty("serverFlag.local");
    	if(serverLocalFalg!=null&&!"false".equals(serverLocalFalg)){//  != false  &&   notnull  是本地服务   
            hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.local.dialect"));
    	}else{
            hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
    	}
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
        // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
        
//        hibernateProperties.setProperty("hibernate.cache.provider_class", env.getProperty("hibernate.cache.provider_class"));
        hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
        hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
        hibernateProperties.setProperty("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class")); 
        hibernateProperties.setProperty("hibernate.cache.provider_configuration", env.getProperty("hibernate.cache.provider_configuration"));     
//        hibernateProperties.setProperty("hibernate.net.sf.ehcache.configurationResourceName", env.getProperty("hibernate.net.sf.ehcache.configurationResourceName"));  
        
        return hibernateProperties;
    }

}